package gr.atc.epart;

import java.util.Locale;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;


public class EPartMaps extends MapActivity
{
	private static MapView _mapView;
	private GeoPoint _lastKnownPosition;
	private PositionUpdateHandler _positionUpdateHandler;
	private boolean _isSatelliteView; 
	private boolean _isTrafficViewActive;
	private boolean _isStreetViewActive;
	private boolean _isGPSTrackingActive;
	
	class MapOverlay extends com.google.android.maps.Overlay
    {
        public boolean draw(Canvas canvas, MapView mapView, 
        boolean shadow, long when) 
        {
            super.draw(canvas, mapView, shadow);                   
 
            //---translate the GeoPoint to screen pixels---
            Point screenPts = new Point();
            mapView.getProjection().toPixels(_lastKnownPosition, screenPts);
 
            //---add the marker---
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.red_pin_3);    
            canvas.drawBitmap(bmp, screenPts.x-8, screenPts.y-30, null);         

            return true;
        }
        
        public boolean onTouchEvent(MotionEvent event, MapView mapView) 
        {   
        	
            //---when user lifts his finger, geocode the point 
            if (event.getAction() == 1) 
            {                
                GeoPoint p = mapView.getProjection().fromPixels(
                    (int) event.getX(),
                    (int) event.getY());
                   
                   String address = EParticipationServicesProvider.getInstance().reverseGeocode(p, Locale.getDefault().getDisplayLanguage(),1);
                    
                   Toast.makeText(getBaseContext(), 
                        address +"("+p.getLatitudeE6() / 1E6 + "," + 
                        p.getLongitudeE6() /1E6 +")", 
                        Toast.LENGTH_LONG).show();
            }                            
            return false;

        }        
    } 
	
	@Override
	public void onCreate(Bundle savedInstanceState) 
	{
		//
		// before attempting to use it see
		// http://code.google.com/android/add-ons/google-apis/mapkey.html
		// the key is created based on the debug certificate installed 
		// (when ready for production this should be revisited)
		//
		// if the key is not correct only grey tiles are displayed
		// see  
		// http://groups.google.com/group/android-developers/browse_thread/thread/d58e1a54a91db7c7/8c1b334edccefe2b?show_docid=8c1b334edccefe2b
		// 
		// According to a forum thread, the "Custom debug keystore" setting (empty by default) should be set to 
		// the same value as the "Default debug keystore" in the Eclipse preferences.(it seems to work with or without this)
		//
		//
		// In general, the procedure is this:
		//
		// 1) get the MD5 fingerprint of the debug keystore by executing the following command on a terminal
		//    keytool -list -alias alias_name -keystore my-release-key.keystore
		// 
		// The location of key store is located here:
		// 	Windows Vista: C:\Users\<user>\.android\debug.keystore
		// 	Windows XP: C:\Documents and Settings\<user>\.android\debug.keystore
		// 	OS X and Linux: ~/.android/debug.keystore
		// 
		// The default password for the debug keystore is "android"
		//
		// 2) visit the following page
		//  http://code.google.com/android/add-ons/google-apis/maps-api-signup.html
		//  and enter the MD5 fingerprint of the key
		//
		// 3) enter the generated key into the android:apiKey attribute of the mapview (in the layout file)
		//
		//
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mapview);
        
        _mapView = (MapView)findViewById(R.id.mapview);
        _mapView.setBuiltInZoomControls(true);
        setupButtonHandlers();
        setupMapView();
                
    	setInitialLocation();
    	setOverlays();       
        
        _mapView.invalidate();
	}

	private void setOverlays()
	{
        _mapView.getOverlays().add(new ClickReceiver(this));
	}

	private void setInitialLocation()
	{
		LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 	
    	
    	if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
    	{
        	Location lastLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        	if (lastLocation != null)
        	{
        		_lastKnownPosition = new GeoPoint((int)(lastLocation.getLatitude() * 1000000), (int)(lastLocation.getLongitude() * 1000000));
        	}
        	else
        	{
            	_lastKnownPosition = new GeoPoint(0,0);
        	}
    	}
    	else
    	{
        	_lastKnownPosition = new GeoPoint(0,0);
    	}
    	_mapView.getController().setZoom(14);
	}
	
	@Override
	protected boolean isRouteDisplayed()
	{
		return false;
	}

	private class ClickReceiver extends Overlay
	{
		 private Context _context;
		 
		 public ClickReceiver(Context context)
		 {
			 _context = context; 
		 }
		 
		 @Override
		 public boolean onTap(GeoPoint p,MapView mapView)
		 {
			 if (mapView.isStreetView())
			 {
				 Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse(("google.streetview:cbll="+(float)p.getLatitudeE6()/1000000f+","+(float)p.getLongitudeE6()/1000000f+"&cbp=1,180,,0,1.0")));
				 
				 _context.startActivity(intent);
				 return true;
			 }
			 
			 return false;
		 }
		
	}
	
	private class PositionUpdateHandler implements LocationListener {

		public void onLocationChanged(Location location) {
			int lat = (int) (location.getLatitude() * 1E6);
			int lng = (int) (location.getLongitude() * 1E6);
			_lastKnownPosition = new GeoPoint(lat, lng);
		    _mapView.getController().setCenter(_lastKnownPosition);
		}


		public void onProviderDisabled(String provider) 
		{
		}

	
		public void onProviderEnabled(String provider) 
		{
		}

	
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	}

	private void setupButtonHandlers()
	{
		// Set up the button for "Zoom In"
    	Button bt = (Button)findViewById(R.id.zoomin);
    	bt.setOnClickListener(new OnClickListener()
    	{       
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    	    	zoomIn();
    		}
    	});  

    	// Set up the button for "Zoom Out"
    	bt = (Button)findViewById(R.id.zoomout);
    	bt.setOnClickListener(new OnClickListener()
    	{
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    		zoomOut();       
    	    }
    	});  

    	// Set up the button for "Pan North"
    	bt = (Button)findViewById(R.id.pannorth);            
    	bt.setOnClickListener(new OnClickListener()
    	{
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    		panNorth();       
    	    }
    	});  

    	// Set up the button for "Pan East"
    	bt = (Button)findViewById(R.id.paneast);
    	bt.setOnClickListener(new OnClickListener()
    	{
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    		panEast();       
    	    }
    	});  

    	// Set up the button for "Pan West"
    	bt = (Button)findViewById(R.id.panwest);
    	bt.setOnClickListener(new OnClickListener()
    	{       
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    		panWest();       
    	    }
    	});  
    	
    	// Set up the button for "Pan South"
    	bt = (Button)findViewById(R.id.pansouth);
    	bt.setOnClickListener(new OnClickListener()
    	{
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    		panSouth();       
    	    }
    	});

    	// Set up the button for "GPS"
    	bt = (Button)findViewById(R.id.gpsview);
    	bt.setOnClickListener(new OnClickListener()
    	{
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    		  switchGPSTracking();       
    	    }

    	});  
    	
    	// Set up the button for "Satellite toggle"
    	bt = (Button)findViewById(R.id.satview);
    	bt.setOnClickListener(new OnClickListener()
    	{
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    	    	switchRoadViewtoSatView();       
    	    }
    	});  
    	
    	// Set up the button for "Traffic toggle"
    	bt = (Button)findViewById(R.id.trafficview);            
    	bt.setOnClickListener(new OnClickListener()
    	{
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    	    	switchTrafficView();
    		}
    	}); 

    	// Set up the button for "Street toggle"
    	bt = (Button)findViewById(R.id.streetview);            
    	bt.setOnClickListener(new OnClickListener()
    	{
    	    // @Override       
    	    public void onClick(View arg0) 
    	    {	   
    	    	switchStreeView();
    		}
    	}); 

	}
	
	public void panWest() 
	{
		GeoPoint pt = new GeoPoint(
				_mapView.getMapCenter().getLatitudeE6(),		
				_mapView.getMapCenter().getLongitudeE6()
				- _mapView.getLongitudeSpan() / 4);

		_mapView.getController().setCenter(pt);  
	}

	public void panEast() 
	{	
		GeoPoint pt = new GeoPoint(
				_mapView.getMapCenter().getLatitudeE6(),		
				_mapView.getMapCenter().getLongitudeE6()
				+ _mapView.getLongitudeSpan() / 4);

		_mapView.getController().setCenter(pt);  
	}

	public void panNorth() 
	{	
		GeoPoint pt = new GeoPoint(
				_mapView.getMapCenter().getLatitudeE6()
				+ _mapView.getLatitudeSpan() / 4,
				_mapView.getMapCenter().getLongitudeE6());	
		_mapView.getController().setCenter(pt);  
	}

	public void panSouth() 
	{	
		GeoPoint pt = new GeoPoint(
				_mapView.getMapCenter().getLatitudeE6()
				- _mapView.getLatitudeSpan() / 4,
				_mapView.getMapCenter().getLongitudeE6());	
		_mapView.getController().setCenter(pt);
	}

	public void zoomIn() 
	{
		_mapView.getController().setZoom(_mapView.getZoomLevel() + 1);
	}

	public void zoomOut() {
		_mapView.getController().setZoom(_mapView.getZoomLevel() - 1);
	}
	
	public void switchRoadViewtoSatView()
	{
		stopGPSTracking();
		_isSatelliteView = !_isSatelliteView;
		_mapView.setSatellite(_isSatelliteView);
		_mapView.invalidate();
	}
	
	public void switchTrafficView() 
	{	
		stopGPSTracking();
		_isTrafficViewActive = !_isTrafficViewActive;
		_mapView.setTraffic(_isTrafficViewActive);
		_mapView.invalidate();
	}

	public void switchStreeView() 
	{	
		stopGPSTracking();
		_isStreetViewActive = !_isStreetViewActive;
		_mapView.setStreetView(_isStreetViewActive);
		_mapView.invalidate();
	}

	public void switchGPSTracking()
	{
		_isGPSTrackingActive = !_isGPSTrackingActive;
		
		if (_isGPSTrackingActive)
			startGPSTracking();
		else
			stopGPSTracking();
	}
	
	private void setupMapView()
	{
		// TODO Auto-generated method stub
		_isSatelliteView = false;
		_isStreetViewActive = false;
		_isTrafficViewActive = false;
		_isGPSTrackingActive = false;
		
		_mapView.setSatellite(_isSatelliteView);
		_mapView.setTraffic(_isTrafficViewActive);
		_mapView.setStreetView(_isStreetViewActive);
	}
	
	private void startGPSTracking()
	{
    	LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 	
    	
    	if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
    	{
    		if (_positionUpdateHandler == null)
    			_positionUpdateHandler = new PositionUpdateHandler();
    		
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0,0, _positionUpdateHandler);
    	}
	}
	
	private void stopGPSTracking()
	{
    	LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE); 	
    	
    	if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
    	{
    		if (_positionUpdateHandler != null)
                locationManager.removeUpdates(_positionUpdateHandler);
    	}
	}
}
